package cn.chenfeifx.checker.thread;

import cn.chenfeifx.checker.CheckerApp;
import cn.chenfeifx.checker.eneity.ExportDataModel;
import cn.chenfeifx.checker.eneity.MessageEntity;
import cn.chenfeifx.checker.eneity.Report;
import cn.chenfeifx.checker.eneity.ReportEntity;
import cn.chenfeifx.checker.enums.CheckerEnum;
import cn.chenfeifx.checker.util.DateUtil;
import cn.chenfeifx.checker.util.ImageBlankChecker;
import cn.chenfeifx.checker.util.MD5Checker;
import cn.chenfeifx.checker.util.SmartImageUtil;
import cn.chenfeifx.core.controls.CFTableView;
import com.alibaba.excel.util.StringUtils;
import javafx.scene.control.TableView;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CheckRunable2 implements Runnable{


    private String filePath;
    private ReportEntity report;
    private Integer index;

    private static final Map<String, Set<Map<String, String>>> dataMap = new ConcurrentHashMap<>();

    public CheckRunable2(Integer index, ReportEntity report, String filePath) {
        this.index = index;
        this.filePath = filePath;
        this.report = report;
    }

    @Override
    public void run() {
        List<MessageEntity> messageList = new ArrayList<MessageEntity>();
        String reference = report.getReference();

        ExportDataModel exportDataModel = new ExportDataModel();
        exportDataModel.setArchiveId(reference);

        exportDataModel.setFileIntegrity("√");
        exportDataModel.setFileAccuracy("√");
        exportDataModel.setMaterialCatalogAccuracy("√");
        exportDataModel.setMaterialCatalogIntegrity("√");
        exportDataModel.setMaterialCatalogMatching("√");
        exportDataModel.setPictureClarity("√");

        exportDataModel.setPictureMatching("√");
        exportDataModel.setPictureRepeatability("√");
        exportDataModel.setMaterialCatalogRepeatability("√");
        if(StringUtils.isEmpty(report.getCompleteNumber()) ||
                StringUtils.isEmpty(report.getCategoryNumber()) ||
                StringUtils.isEmpty(report.getCaseNumber()) ||
                StringUtils.isEmpty(report.getReference()) ||
                StringUtils.isEmpty(report.getAuthor()) ||
                StringUtils.isEmpty(report.getReferenceNumber()) ||
                StringUtils.isEmpty(report.getTitleName()) ||
                StringUtils.isEmpty(report.getDate()) ||
                report.getPageNumber() == null ||
                report.getYear() == null ||
                StringUtils.isEmpty(report.getTerm()) ||
                //StringUtils.isEmpty(report.getSecurity()) ||
                StringUtils.isEmpty(report.getOpenState())
                //StringUtils.isEmpty(report.getRemark()) ||
                ) {
            messageList.add(new MessageEntity(reference, "案卷目录不全"));
            System.out.println(reference + "一文一件案卷目录不全");
            exportDataModel.setFileIntegrity("✖");
            CheckerApp.getInstance().setMessageList(CheckerEnum.ONE_PIECE.getCode(),messageList);
            CFTableView cfTableView = CheckerApp.getInstance().getCfTableView2();
            TableView tableView = cfTableView.getTableView();
            List<ReportEntity> items = tableView.getItems();
            ReportEntity report1 = items.get(index - 1);
            report1.setStatusPath("/img/cha.png");
            cfTableView.refresh();
        }
        if (StringUtils.isEmpty(report.getDate())) {
            messageList.add(new MessageEntity(reference, "案卷日期不能为空"));
            exportDataModel.setFileIntegrity("✖");
        }else { //校验日期
            boolean flag = DateUtil.checkDate(report.getDate());
            if (!flag) {
                messageList.add(new MessageEntity(reference,"日期格式不正确"));
                exportDataModel.setFileAccuracy("✖");
            }
        }

        boolean flag = DateUtil.checkYear(report.getYear() + "");
        if(!flag){
            messageList.add(new MessageEntity(reference,"年度格式不正确"));
            exportDataModel.setFileAccuracy("✖");
        }
        if (!StringUtils.isEmpty(report.getAuthor())) {
            boolean flag1 = checkName(report.getAuthor());
            if (!flag1) {
                messageList.add(new MessageEntity(reference,"责任人不正确"));
                exportDataModel.setFileAccuracy("✖");
            }
        }

        List<String> newFilenames = new ArrayList<>();
        Set<String> knownHashes = new HashSet<>();

        /*Path dir = Paths.get(filePath);
        Path parent = dir.getParent();
        URI uri = parent.toUri();
        String urlStr = uri.toString();
        String url = urlStr + "/图片" + report.getReference();*/
        String url = filePath+"/"+report.getReference();

        Integer pagenumber = 0;
        List<String> fileNames = new ArrayList<>();
        //获取档号路径下所有的图片
        File folder = new File(url);
        if (folder.exists()) {
            File[] fileList = folder.listFiles();
            if (fileList != null) {
                for (File filedir : fileList) {
                    String fileName = filedir.getName();
                    if(isImageFile(fileName)) {
                        fileNames.add(fileName);
                        String path = filedir.getPath();
                        newFilenames.add(path);
                        pagenumber++;
                    }
                    /*File[] imageFiles = filedir.listFiles();
                    if (imageFiles != null) {
                        for (File imageFile : imageFiles) {
                            if (isImageFile(imageFile.getName())) {
                                //HashMap<String, String> map = new HashMap<>();
                                //map.put(imageFile.getPath(), imageFile.getName());
                                //numberset.add(map);
                                String fileName = imageFile.getName();
                                fileNames.add(fileName);
                                String path = imageFile.getPath();
                                newFilenames.add(path);
                                pagenumber++;
                            }
                        }
                    }*/

                }
            }
        }

        if (!newFilenames.isEmpty()) {
            for (String newname : newFilenames) {
                boolean b = checkImage(reference, newname, knownHashes, messageList, exportDataModel);
            }
        }

        //图片排序
        checkSequenceContinuity(fileNames, reference, messageList, exportDataModel);

        // 页数
        if (newFilenames.size() != report.getPageNumber()) {
            exportDataModel.setPictureMatching("✖");
            exportDataModel.setMaterialCatalogMatching("✖");
            exportDataModel.setMaterialCatalogIntegrity("✖");
            //exportDataModel.setPictureClarity("✖");
            messageList.add(new MessageEntity(reference, "案卷目录页数不对"));
        }

        /*for (MessageEntity messageEntity : messageList) {
            System.out.println(messageEntity.getMessage());
            CheckerApp.getInstance().getMessageList(CheckerEnum.ONE_PIECE.getCode()).add(messageEntity);
        }*/
        CheckerApp.getInstance().setMessageList(CheckerEnum.ONE_PIECE.getCode(), messageList);

        exportDataModel.setPictureCount(pagenumber);
        //CheckerApp.getInstance().getReports(CheckerEnum.ONE_PIECE.getCode()).add(exportDataModel);
        exportDataModel.setMaterialCatalogCount("/");
        CheckerApp.getInstance().setReport(CheckerEnum.ONE_PIECE.getCode(), exportDataModel);
        CFTableView cfTableView = CheckerApp.getInstance().getCfTableView2();
        TableView tableView = cfTableView.getTableView();
        List<ReportEntity> items = tableView.getItems();
        ReportEntity report1 = items.get(index - 1);
        report1.setStatusPath("/img/right.png");
        cfTableView.refresh();
    }

    private static boolean isImageFile(String name) {
        String imageExtension = name.toLowerCase();
        return imageExtension.endsWith(".jpg") ||
                imageExtension.endsWith(".jpeg") ||
                imageExtension.endsWith(".png") ||
                imageExtension.endsWith(".gif");
    }


    private static boolean checkImage(String reference, String path, Set<String> knownHashes, List<MessageEntity> messageList, ExportDataModel exportDataModel) {
        boolean picNotReadable = false;
        boolean picRepeat = false;
        boolean picBlank = false;
        boolean picDpi = false;
        boolean picColorDepth = false;
        boolean isValidFileName = false;
        Path startPath = Paths.get(path);
        // 检查路径是否存在
        if (Files.exists(startPath)) {
            try {
                System.out.println(path);
                String filepath = path.toString();
                //校验图片命名是否合规
                String[] picNames = filepath.split("\"");
                String picName = picNames[picNames.length - 1];
                if (!isValidFileName(picName)) {
                    messageList.add(new MessageEntity(reference, path + "图片文件命名不合规"));
                    exportDataModel.setFileIntegrity("✖");
                    isValidFileName = true;
                }
                String fileMD5 = MD5Checker.getFileMD5(path.toString());
                // 检查MD5哈希值是否表示文件重复
                if (knownHashes.contains(fileMD5)) {
                    messageList.add(new MessageEntity(reference, path + " 文件重复"));
                    exportDataModel.setMaterialCatalogRepeatability("✖");
                    exportDataModel.setPictureRepeatability("✖");
                    picRepeat = true;
                } else {
                    knownHashes.add(fileMD5);
                }
                //判断图片是否可读
                boolean imageReadable = SmartImageUtil.isImageReadable(path.toString());
                if (!imageReadable) {
                    messageList.add(new MessageEntity(reference, path + " 图片不可读"));
                    picNotReadable = true;
                    exportDataModel.setPictureMatching("✖");

                } else {
                    //判断图片是否为空白
                    boolean imageBlank = ImageBlankChecker.isImageBlank(path.toString(), 10);
                    if (imageBlank) {
                        messageList.add(new MessageEntity(filepath, "图片空白"));
                        picBlank = true;
                        exportDataModel.setPictureMatching("✖");

                    }

                    if (!SmartImageUtil.checkPPI(path.toString())) {
                        messageList.add(new MessageEntity(filepath, "图片DPI不达标"));
                        picDpi = true;
                        exportDataModel.setPictureClarity("✖");

                    }
                    if (!SmartImageUtil.checkColorDepth(path.toString())) {
                        messageList.add(new MessageEntity(filepath, "图片颜色深度不达标"));
                        exportDataModel.setPictureClarity("✖");
                        picColorDepth = true;
                    }

                }

                //判断图片是否有黑边
                boolean flag = SmartImageUtil.detectBlackBorder(path.toString());
                if (flag) {
                    messageList.add(new MessageEntity(filepath,"图片有黑边"));
                    exportDataModel.setPictureClarity("✖");
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
            if (picNotReadable || picRepeat || picBlank || picDpi || picColorDepth || isValidFileName) {
                return false;
            }

        } else {
            exportDataModel.setMaterialCatalogAccuracy("✖");
            messageList.add(new MessageEntity(reference, startPath + " 路径不存在，文件夹为空。"));
        }
        return true;
    }

    public static boolean isValidFileName(String fileName) {

        String fileNameRegex = "([^\\\\\\\\]+)$";

        Pattern pattern = Pattern.compile(fileNameRegex);
        Matcher matcher = pattern.matcher(fileName);

        if (matcher.find())
            fileName = matcher.group(1);


        // 正则表达式，匹配 "A046-1·2017·1-0001001.JPG" 格式
        // 正则表达式模式
        //String regex = "^A\\d{3}-\\d{1}·\\d{4}-\\d{1}-\\d{4}-\\d{3}\\.(JPG|jpg)$";
        //String regex = "^A\\d{3}-\\d·\\d{4}·\\d-\\d{7}\\.(?i)jpg$";
        //String regex = "^AY\\d{3}-\\d{1}·\\d{1}-\\d{3}-\\d{6}\\.jpg$";
        String regex = "^[A-Z]{1}\\d{3}-\\d{1}·\\d{4}·\\d{1}-\\d{7}\\.jpg$";
        pattern = Pattern.compile(regex);
        matcher = pattern.matcher(fileName);
        return matcher.matches();
    }

    public static void checkSequenceContinuity(List<String> fileNames, String reference, List<MessageEntity> messageList, ExportDataModel exportDataModel) {
        System.out.println("图片顺序号排序检测开始");
        // 使用TreeMap保存文件名和序号
        List<String> sequenceList = new ArrayList<>();

        for (String fileName : fileNames) {
            String[] str = fileName.split("-");
            String s = str[str.length - 1];
            String substring = s.substring(0, s.length() - 4);
            sequenceList.add(substring.substring(substring.length() - 3));
        }

        Collections.sort(sequenceList);

        for (int i = 1; i < sequenceList.size(); i++) {
            int prevSeq = Integer.parseInt(sequenceList.get(i - 1));
            int currentSeq = Integer.parseInt(sequenceList.get(i));
            int poor = currentSeq - prevSeq;
            if (currentSeq != prevSeq + 1) {
                if (poor > 1) {
                    for (int j = 1; j < poor; j++) {
                        messageList.add(new MessageEntity(reference, "图片编号顺序不连续,缺少" + String.format("000%d", prevSeq + j)));
                        exportDataModel.setFileIntegrity("✖");
                    }
                } else {
                    messageList.add(new MessageEntity(reference, "图片编号顺序不连续,缺少" + String.format("000%d", prevSeq + 1)));
                    exportDataModel.setFileIntegrity("✖");
                }
            }
        }
        System.out.println("图片顺序号排序检测结束");
    }

    public static int getSubFolderCount(String url) {
        File folder = new File(url);
        File[] files = folder.listFiles();
        int count = 0;
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    count++;
                }
            }
        }
        return count;
    }

    public static boolean checkName(String author) {
        //String regex = "^[\\u4e00-\\u9fff\\u3400-\\u4dbf\\u20000-\\u2a6df\\u2a700-\\u2b73f\\u2b740-\\u2b81f\\u2b820-\\u2ceaf\\u2ceb0-\\u2ebef]+$";
        String regex = "^[\\u4e00-\\u9fff]+$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(author);
        return matcher.matches();
    }

    public static void main(String[] args) {
        String author = "吉亚欢";
        System.out.println(checkName(author));
    }
}
